﻿using System.Linq;

using SPR.Helpers;

using Styx;

using TreeSharp;

namespace SPR.Classes.Shaman
{
    using System.Text;
    using global::SPR.Lists;
    using Styx.WoWInternals;

    public class Enhancement : RotationBase
    {
        public override string Name
        {
            get { return "Enhancement Shaman"; }
        }

        #region KeySpell
        public override string KeySpell
        {
            get { return "Lava Lash"; }
        }
        #endregion

        #region Help
        public override string Help
        {
            get
            {
                return "\n" +
                    "----------\n" +
                    "ST_0 \n" +
                    "SS \n" +
                    "LL \n" +
                    "MW5_LB \n" +
                    "FS_UEF \n" +
                    "UE \n" +
                    "ES \n" +
                    "SW \n" +
                    "ST \n" +
                    "----------\n";
            }
        } 
        #endregion

        #region DPS
        public override Composite SingleRotation
        {
            get
            {
                return new PrioritySelector(
                    /*
                    SC.CastSpell("Lightning Bolt", a => SC.PlayerCountBuff("Maelstrom Weapon") > 4, "Lightning Bolt"),
                    SC.CastSpell("Lightning Shield", a => !SC.PlayerHasBuff("Lightning Shield"), "Lightning Shield"),
                    SC.CastSpell("Feral Spirit", a => Me.CurrentTarget.CurrentHealth > 1500000 || Me.CurrentTarget.MaxHealth == 1, "Feral Spirit"),
                    SC.UseTrinket(77113, ret => true, "Kiroptyric Sigil"), //Add your own trinket search wowhead use the item ID
                    SC.CastSpell("Blood Fury", a => SC.IsUsableSpell("Blood Fury"), "Blood Fury"), //Orc thing
                    SC.CastSpell("Berserking", a => SC.IsUsableSpell("Berserking"), "Berserking"), //Troll Thing
                    SC.CastSpell("Rocket Barrage", a => SC.IsUsableSpell("Rocket Barrage"), "Rocket Barrage"), //Goblin Thing
                    SC.UseEngineerGloves(a => true, "Engineer Gloves"),
                    SC.CastSpell("Call of the Elements", a => !ChkTotem("Strength of Earth Totem"), "Call of the Elements"),
                    SC.CastSpell("Searing Totem", a => !ChkTotem("Searing Totem"), "Searing Totem"),
                    SC.CastSpell("Stormstrike", a => true, "Stormstrike"),
                    SC.CastSpell("Lava Lash", a => true, "Lava Lash"),
                    SC.CastSpell("Unleash Elements", a => true, "Unleash Elements"),
                    SC.CastSpell("Flame Shock", a => SC.PlayerHasBuff("Unleash Flame"), "Flame Shock"),
                    SC.CastSpell("Earth Shock", a => SC.TargetDebuffTimeLeft("Flame Shock") > 5, "Earth Shock"),
                    SC.CastSpell("Chain Lightning", a => Me.GotTarget && AOECHK(Me.CurrentTarget.Location, 8).Count >= 2 && SC.PlayerCountBuff("Maelstrom Weapon") == 5, "Chain Lightning"),
                    SC.CastSpell("Fire Nova", a => Me.GotTarget && AOECHK(Me.CurrentTarget.Location, 8).Count >= 2, "Fire Nova")
                    //SC.CastSpell("Wind Shear", a => Me.GotTarget && Me.CurrentTarget.IsCasting, "Wind Shear"), // Disabled by Default
                    */
                    new Decorator(
                        ret => Units.IsTargetWorthy(Me.CurrentTarget),
                            new PrioritySelector(
                                Item.UseTrinkets(),
                                Spells.UseRacials(),
                                Buff.CastBuff("Lifeblood", ret => true, "Lifeblood"),
                                Items.UseBagItem("Potion of the Tolvir", ret => Buffs.UnitHasHasteBuff(Me), "Potion of Tolvir"),
                                Items.UseEngineerGloves(ret => true, "Engineer's gloves")
                            )
                    ),
                    // Extra button automation
                    Items.RunMacroText("/click ExtraActionButton1", ret => (Units.IsFadingLight() || Units.IsShrapnel() || Units.IsHourofTwilight()) && SPR.Instance.AutoExtraActionButton, "[Push Button] ExtraActionButton1"),
                    Buff.CastBuff("Lightning Shield", ret => !Buff.PlayerHasBuff("Lightning Shield"), "No Shield Buff - Lightning Shield"),
                    // Interrupts
                    //Spells.CastInterupt("Wind Shear", ret => true, "Wind Shear"),
                    //ST_0
                    Items.RunMacroText("/cast Call of the Elements", ret => !(Helpers.Player.ChkTotem("Searing Totem") || Helpers.Player.ChkTotem("Fire Elemental Totem")), "Calll of the Elements"),
                    // AOE
                    new Decorator(
                        ret => Units.CountEnnemiesInRange(Me.CurrentTarget.Location, 15) > 2 & SPR.Instance.AutoAoe,
                        new PrioritySelector(
                            // FS
                            Spells.CastSpell("Flame Shock", ret => !Buff.TargetHasDebuff("Flame Shock"), "AOE - Flame Shock"),
                            // UE
                            Spells.CastSpell("Unleash Elements", ret => true, "AOE - Unleash Elements"),
                            // LL
                            Spells.CastSpell("Lava Lush", ret => true, "Aoe - Lava Lash"),
                            // FN
                            Spells.CastSpell("Fire Nova", ret => Buff.TargetHasDebuff("Flame Shock"), "AOE - Fire Nova"),
                            // MW5_CL
                            Spells.CastSpell("Chain Lightning", ret => Buff.PlayerCountBuff("Maelstrom Weapon") > 4 && Units.CountEnnemiesInRange(Me.CurrentTarget.Location, 15) > 1, "AOE - Chain Lightning")
                        )
                    ),
                    new Decorator(ret => true,
                        new PrioritySelector(
                            // SS
                            Spells.CastSpell("Stormstrike", ret => true, "Stormstrike"),
                            // LL
                            Spells.CastSpell("Lava Lash", ret => true, "Lava Lash"),
                            // MW5_LB
                            Spells.CastSpell("Chain Lightning", ret => PlayerCountBuff("Maelstrom Weapon") > 4 && Units.CountEnnemiesInRange(Me.CurrentTarget.Location, 15) > 1, "MW_5 Chain Lightning"),
                            Spells.CastSpell("Lightning Bolt", ret => PlayerCountBuff("Maelstrom Weapon") > 4, "MW5 Lightning Bolt"),
                            // FS_UEF
                            Spells.CastSpell("Flame Shock", ret => Buff.PlayerHasActiveBuff("Unleash Flame"), "Flame Shock on Unleash Flame"),
                            // UE
                            Spells.CastSpell("Unleash Elements", ret => true, "Unleash Elements"),
                            // ES
                            Spells.CastSpell("Earth Shock", ret => Buff.TargetDebuffTimeLeft("Flame Shock").TotalSeconds > 5, "Earth Shock"),
                            // SW
                            Spells.CastSpell("Feral Spirit", ret => Units.IsTargetWorthy(Me.CurrentTarget) && Buff.PlayerCountBuff("Combat Trance") == 10, "Feral Spirit")
                        )
                    )
                );
            }
        }
        #endregion

        #region Combat Distance
        /* public override float CombatMaxDistance // disabled for madness DW fight & other boss with big hitbox
         {
             get
             {
                 return 5f;
             }
         }*/
        #endregion

        #region Totem Stuff
        private static bool ChkTotem(string totem)
        {
            bool totchk = false;
            foreach (Styx.WoWInternals.WoWObjects.WoWTotemInfo ti in Me.Totems)
            {
                if (ti.Name == totem)
                    totchk = true;
            }
            return totchk;
        }
        #endregion

        /*
        #region Aoe Stuff
        public List<WoWUnit> AOECHK(WoWPoint chkloc, double radius)
        {
            List<WoWUnit> hostile = ObjectManager.GetObjectsOfType<WoWUnit>(true, false);
            List<WoWUnit> avoid = new List<WoWUnit>();
            var MaxDistance2 = radius * radius;
            try
            {
                hostile = hostile.Where(x =>
                    x.IsAlive &&
                    (x.IsTargetingMeOrPet || x.IsTargetingMyPartyMember || x.IsTargetingMyRaidMember || x.IsTargetingPet) &&
                    !x.IsCritter &&
                    !x.IsPet &&
                    x.Location.Distance2DSqr(chkloc) < MaxDistance2
                ).ToList();
                avoid = hostile.Where(x =>
                    //check for controlled units, like sheep etc
                SimCraftBase.Instance.UnitIsControlled(x, true)
                ).ToList();
                if (avoid != null && avoid.Count > 0)
                {
                    hostile = null;
                    hostile.Add(Me.CurrentTarget);
                }
            }
            catch { }
            return hostile;
        }
        #endregion
        */
        
        #region Buffs & Wep Imbue
        public override Composite PreCombat
        {
            get
            {
                return new Decorator(
                    ret => !Me.Mounted && !Me.Dead && !Me.Combat && !Me.IsFlying && !Me.IsOnTransport && !Me.HasAura("Food") && !Me.HasAura("Drink"),
                    new PrioritySelector(
                        Buff.CastBuff("Lightning Shield", ret => !Buff.PlayerHasBuff("Lightning Shield"), "No Shield Buff - Lightning Shield"),
                        Buff.CastBuff("Windfury Weapon", ret => Me.Inventory.Equipped.MainHand.TemporaryEnchantment.Id != 283, "Windfury Weapon"),
                        Buff.CastBuff("Flametongue Weapon", ret => Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id != 5, "Flametongue Weapon")));
            }
        }
        #endregion

        #region PvP (Not Used)
        public override Composite PVPRotation
        {
            get
            {
                return new PrioritySelector(

                );
            }
        }

        public override Composite PVERotation
        {
            get { return SingleRotation; }
        }
        #endregion

        public override Composite Medic
        {
            get
            {
                return new Decorator(
                    ret => Me.HealthPercent < 100,
                    new PrioritySelector(
                        Items.UseBagItem("Healthstone", ret => Me.HealthPercent < 30, "Healthstone")));
            }
        }

        public int PlayerCountBuff(string name)
        {
            try
            {
                var lua = string.Format("local x=select(4, UnitBuff('player', \"{0}\")); if x==nil then return 0 else return x end", RealLuaEscape(name));
                var t = int.Parse(Lua.GetReturnValues(lua)[0]);
                return t;
            }
            catch
            {
                SPR.Instance.Log("Lua failed in PlayerCountBuff");
                return 0;
            }
        }
        public static string RealLuaEscape(string luastring)
        {
            var bytes = UTF8Encoding.UTF8.GetBytes(luastring);
            var ret = "";
            foreach (var b in bytes)
            {
                ret += "\\" + b;
            }
            return ret;
        }
    }
}